
package dialogs;

import core.COINCOMOComponent;
import core.COINCOMOSystem;
import core.COINCOMOUnit;
import database.COINCOMOSystemManager;
import extensions.COINCOMOTreeNode;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import main.GlobalMethods;
import main.Icons;
import panels.HierarchyPanel;
import panels.OverviewsAndGraphsPanel;

/**
 *
 * @author Raed Shomali
 */
public class ViewProjectsDialog extends JDialog implements ActionListener
{
    Container c = getContentPane();

    JButton loadButton = new JButton( "Load" );

    JButton deleteButton = new JButton( "Delete" );

    JButton closeButton = new JButton( "Close" );

    DefaultListModel listModel = new DefaultListModel();

    JList availableSystemsList = new JList( listModel );

    JScrollPane listScroller = new JScrollPane( availableSystemsList );

    public static Vector<COINCOMOSystem> allSystems = null;

    /**
     * 
     * @param parentFrame is the original frame that generated this Dialog
     */
    public ViewProjectsDialog( JFrame parentFrame )
    {
        super( parentFrame );

        this.setTitle( "View Projects..." );
        this.setModal( true );

        // Buttons
        loadButton.addActionListener( this );
        deleteButton.addActionListener( this );
        closeButton.addActionListener( this );

        loadButton.setFocusable( false );
        deleteButton.setFocusable( false );
        closeButton.setFocusable( false );

        loadButton.setIcon( Icons.LOAD_PROJECT_ICON );
        deleteButton.setIcon( Icons.DELETE_PROJECT_ICON );
        closeButton.setIcon( Icons.CLOSE_ICON );

        // List
        TitledBorder availableSystemsTitleBorder = BorderFactory.createTitledBorder( "Available Systems" );
        availableSystemsTitleBorder.setTitleColor( Color.DARK_GRAY );
        availableSystemsTitleBorder.setTitlePosition( TitledBorder.BELOW_TOP );
        availableSystemsTitleBorder.setTitleJustification( TitledBorder.CENTER );
        listScroller.setBorder( availableSystemsTitleBorder );

        // GUI
        c.setLayout( null );

        c.add( listScroller );

        c.add( loadButton );
        c.add( deleteButton );
        c.add( closeButton );

        listScroller.setBounds( 20 , 20 , 290 , 220 );

        loadButton.setBounds( 20 , 260 , 90 , 25 );
        deleteButton.setBounds( 120 , 260 , 90 , 25 );
        closeButton.setBounds( 220 , 260 , 90 , 25 );

        GlobalMethods.updateStatusBar( "Loading Available Systems ..." ) ;
        
        loadButton.setEnabled( false ) ;
        deleteButton.setEnabled( false ) ;
        closeButton.setEnabled( false ) ;
        
        // Update in a GUI Thread
        SwingUtilities.invokeLater( new Runnable()
        {
            public void run()
            {
                try
                {
                    // Rest a Bit ... So the GUI would Render
                    Thread.sleep( 100 );

                    allSystems = COINCOMOSystemManager.getAllSystems();

                    for ( int i = 0 ; i < allSystems.size() ; i++ )
                    {
                        COINCOMOSystem tempSystem = allSystems.get( i );

                        // Add to the list
                        listModel.addElement( tempSystem.getName() );
                    }

                    loadButton.setEnabled( true ) ;
                    deleteButton.setEnabled( true ) ;
                    closeButton.setEnabled( true ) ;
        
                    GlobalMethods.updateStatusBar( "Available Systems have been loaded." );
                }
                catch ( InterruptedException ex )
                {
                }
            }

        } );

        this.setDefaultCloseOperation( JDialog.DISPOSE_ON_CLOSE );
        this.setLocation( this.getOwner().getX() + 100 , this.getOwner().getY() + 100 );
        this.setResizable( false );
        this.setSize( 335 , 330 );
        this.setVisible( true );
    }

    public void actionPerformed( ActionEvent e )
    {
        if ( e.getSource() == loadButton )
        {
            // Is Nothing Selected ?
            if ( availableSystemsList.isSelectionEmpty() )
            {
                GlobalMethods.updateStatusBar( "No System was selected for loading." , Color.RED );
            }
            else
            {
                if ( availableSystemsList.getSelectedIndices().length > 1 )
                {
                    GlobalMethods.updateStatusBar( "One system at most can be selected for loading." , Color.RED );
                }
                else
                {
                    loadButton.setEnabled( false );
                    deleteButton.setEnabled( false );
                    closeButton.setEnabled( false );
                    
                    GlobalMethods.updateStatusBar( "Loading ..." );

                    // Get a Reference of this Current Instance
                    final JDialog currentDialog = this ;
                    
                    SwingUtilities.invokeLater( new Runnable()
                    {
                        public void run()
                        {
                            // Get Selected System
                            COINCOMOSystem system = allSystems.get( availableSystemsList.getSelectedIndex() );

                            // Load System From Database ...
                            COINCOMOSystemManager.loadSystem( system , null ) ;
                            
                            // New Root with New System
                            HierarchyPanel.root = new COINCOMOTreeNode( system );

                            // Update Tree
                            DefaultTreeModel model = (DefaultTreeModel) HierarchyPanel.tree.getModel();
                            model.setRoot( HierarchyPanel.root );
                            
                            // Apply Visually on Tree ...
                            createTree( HierarchyPanel.root , HierarchyPanel.root.getCOINCOMOUnit() ) ;
                            HierarchyPanel.tree.setSelectionPath( new TreePath( HierarchyPanel.root.getPath() ) );
                            
                            loadButton.setEnabled( true );
                            deleteButton.setEnabled( true );
                            closeButton.setEnabled( true );
                        
                            GlobalMethods.updateStatusBar( "Project has been loaded." );

                            currentDialog.dispose();
                        }

                    } );
                }
            }
        }
        else if ( e.getSource() == deleteButton )
        {
            // Is Nothing Selected ?
            if ( availableSystemsList.isSelectionEmpty() )
            {
                GlobalMethods.updateStatusBar( "No System was selected for deletion." , Color.RED );
            }
            else
            {
                int result = JOptionPane.showConfirmDialog( this , "Are you sure you want to continue with the Deletion?" , "Confirm Deletion" , JOptionPane.YES_NO_OPTION ) ;
                
                // If User didnt Select YES ...
                if( result != JOptionPane.YES_OPTION )
                {
                    // Abort Deletion ...
                    return ;
                }
                
                loadButton.setEnabled( false );
                deleteButton.setEnabled( false );
                closeButton.setEnabled( false );

                GlobalMethods.updateStatusBar( "Deleting ..." );

                // Create a Thread
                SwingUtilities.invokeLater( new Runnable()
                {
                    public void run()
                    {
                        int selectedSystems[] = availableSystemsList.getSelectedIndices();

                        final Vector<COINCOMOSystem> systemsToBeDeleted = new Vector<COINCOMOSystem>();

                        for ( int i = 0 ; i < selectedSystems.length ; i++ )
                        {
                            // Remove From GUI
                            listModel.remove( selectedSystems[i] - i );

                            systemsToBeDeleted.add( allSystems.get( selectedSystems[i] ) );
                            
                            // Check If The Current Project is Being Deleted ...
                            if( HierarchyPanel.root != null && ((COINCOMOSystem)allSystems.get( selectedSystems[i] )).getUnitID() == HierarchyPanel.root.getCOINCOMOUnit().getUnitID() )
                            {
                                // Clear Tree
                                DefaultTreeModel model = (DefaultTreeModel) HierarchyPanel.tree.getModel();
                                model.setRoot( null );
                                HierarchyPanel.root = null ;
                                
                                HierarchyPanel.addSubSystemButton.setEnabled( false ) ;
                                HierarchyPanel.addComponentButton.setEnabled( false ) ;
                                HierarchyPanel.deleteSubSystemButton.setEnabled( false ) ;
                                HierarchyPanel.deleteComponentButton.setEnabled( false ) ;
        
                                // If Tabs Exist ...
                                if( OverviewsAndGraphsPanel.tabs.getTabCount() > 0 )
                                {
                                    OverviewsAndGraphsPanel.clearOverviewTab() ;
                                    OverviewsAndGraphsPanel.tabs.setEnabledAt( 1 ,false ) ;
                                }
                            }
                        }

                        // Remove From Database
                        COINCOMOSystemManager.deleteSystems( systemsToBeDeleted );

                        // Refresh Available Systems List ...
                        for( int i = 0 ; i < systemsToBeDeleted.size() ; i ++ )
                        {
                            allSystems.remove( systemsToBeDeleted.get( i ) ) ;
                        }
                        
                        loadButton.setEnabled( true );
                        deleteButton.setEnabled( true );
                        closeButton.setEnabled( true );

                        GlobalMethods.updateStatusBar( "Project(s) have been deleted." );
                    }

                } );
            }
        }
        else
        {
            // Exit ...
            this.dispose();
        }
    }

    public static void createTree( COINCOMOTreeNode parentNode , COINCOMOUnit parentUnit )
    {
        // Get Tree Model For Addition of Nodes ...
        DefaultTreeModel treeModel = (DefaultTreeModel) HierarchyPanel.tree.getModel();
        
        // Get Ordered Vector ..
        Vector<COINCOMOUnit> orderedVector = GlobalMethods.getOrderedVector( parentUnit.getListOfSubUnits() ) ;
        
        // Loop though Sub Units ....
        for( int i = 0 ; i < orderedVector.size() ; i ++ )
        {
            // Define a new Node Tree, give it a name and a type
            COINCOMOTreeNode subUnitNode = new COINCOMOTreeNode( (COINCOMOUnit) orderedVector.get( i ) );

            // Insert in Tree
            treeModel.insertNodeInto( subUnitNode , parentNode , parentNode.getChildCount()  );
            
            // Expand ...
            HierarchyPanel.tree.scrollPathToVisible( new TreePath( subUnitNode.getPath() ) );
        
            // As Long as its not a Component ... Do a Recursive Call ...
            if( !( subUnitNode.getCOINCOMOUnit() instanceof COINCOMOComponent ) )
            {
                createTree( subUnitNode , subUnitNode.getCOINCOMOUnit() ) ;
            }
        }
    }
}
